package {
	
	import alternativa.engine3d.core.Face;
	import alternativa.engine3d.core.Surface;
	import alternativa.engine3d.core.Vertex;
	import alternativa.engine3d.errors.SurfaceExistsError;
	import alternativa.engine3d.errors.VertexExistsError;
	import alternativa.engine3d.materials.FillMaterial;
	
	import flash.display.BlendMode;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.geom.Point;
	import flash.net.URLLoader;
	import flash.net.URLRequest;

	public class Monde extends TextureLoader {
		
		public function Monde() {
			super("monde");
			var chargeur:URLLoader = new URLLoader(new URLRequest("ressources/monde.xml"));
			chargeur.addEventListener(Event.COMPLETE, onXMLLoadComplete);
			chargeur.addEventListener(IOErrorEvent.IO_ERROR, onErrorHandler);			
		}
		
		private function onErrorHandler(event:Event):void {
			trace("Erreur: "+event);
		}
		
		private function onXMLLoadComplete(event:Event):void {
			var modele:XML = new XML(event.target.data);
			loadMurs(modele);
			loadSols(modele);
			load(test);
			dispatchEvent(event);
		}
		
		private function test():void {
			trace("c'est tout bon!");
		}
		
		private function loadSols(modele:XML):void {
			var f:Face;
			var v:Array;
			for each(var sol:XML in modele..sol) {
				v = [];
				for each(var point:XML in sol..point)
					v.push(createVertex(point.@x, point.@y, 0, point.@x+"_"+point.@y+"_"+0));
				f = createFace(v);
				setUVsToFace(new Point(0, 0), new Point(1, 0), new Point(1, 1), f);
				addFaceToSurface(f, sol.@couleur, sol.@texture);
			}
		}
		
		private function loadMurs(modele:XML):void {
			var f:Face;
			for each(var mur:XML in modele..mur) {
				f = addMur(mur.@x1, mur.@y1, mur.@x2, mur.@y2, modele.composition.murs.@hauteur);
				addFaceToSurface(f, mur.@couleur, mur.@texture);
				f = addMur(mur.@x2, mur.@y2, mur.@x1, mur.@y1, modele.composition.murs.@hauteur);
				addFaceToSurface(f, mur.@couleur, mur.@texture, true);
			}
		}
		
		private function addMur(x1:Number, y1:Number, x2:Number, y2:Number, hauteur:Number):Face {
			var v:Array = [];
			var f:Face;
			v.push(createVertex(x1, y1, hauteur, x1+"_"+y1+"_"+hauteur));
			v.push(createVertex(x2, y2, hauteur, x2+"_"+y2+"_"+hauteur));
			v.push(createVertex(x2, y2, 0, x2+"_"+y2+"_"+0));
			v.push(createVertex(x1, y1, 0, x1+"_"+y1+"_"+0));
			f = createFace(v);
			setUVsToFace(new Point(0, 0), new Point(1, 0), new Point(1, 1), f);
			return f;
		}
		
		private function addFaceToSurface(face:Face, couleur:uint, texture:String = "", hide:Boolean = false):Surface {
			var s:Surface;
			if(hide) {
				if(""==texture) {
					s = createSurface(null, couleur.toString()+"_hide");
					setColorToSurface(s, couleur, 0.2);
				} else {
					s = createSurface(null, texture+"_hide");
					setTextureToSurface(s, couleur, texture, 0.3);
				}
			} else {
				if(""==texture) {
					s = createSurface(null, couleur.toString());
					setColorToSurface(s, couleur);
				} else {
					s = createSurface(null, texture);
					setTextureToSurface(s, couleur, texture);
				}
			}
			s.addFace(face);
			return s;
		}
		
		private function setColorToSurface(s:Surface, c:uint, alpha:Number = 1):void {
			setMaterialToSurface(new FillMaterial(c, alpha, BlendMode.NORMAL, 1, 0xffffff), s);
		}
		
		private function setTextureToSurface(s:Surface, c:uint, url:String, alpha:Number = 1):void {
			setColorToSurface(s, c, alpha);
			addBinding(s, "ressources/"+url, alpha);
		}
		
		public override function createSurface(faces:Array=null, id:Object=null):Surface {
			var s:Surface;
			try {
				s = super.createSurface(faces, id);
			} catch(error:SurfaceExistsError) {
				s = getSurfaceById(id);
			}
			return s;
		}
		
		public override function createVertex(x:Number=0, y:Number=0, z:Number=0, id:Object=null):Vertex {
			var v:Vertex;
			try {
				v = super.createVertex(x, y, z, id);
			} catch(error:VertexExistsError) {
				v = getVertexById(id);
			}
			return v;
		}
				
	}
}